package com.ldf.jrtsp.socket;

import com.ldf.jrtsp.callback.BareStreamCallBack;
import com.ldf.jrtsp.conf.RtspConfig;
import com.ldf.jrtsp.enums.MediaType;
import com.ldf.jrtsp.player.RtspPlayer;
import com.ldf.jrtsp.pool.JRtspThreadPool;

import java.util.HashMap;
import java.util.Map;

/**
 * rtsp transport factory
 *
 * @author lidaofu
 * @since 2024/6/20
 **/
public class RtspTransportFactory {
    // rtp port map key is rtp port value is rtsp track
    private final static Map<Integer, String> RTP_PORT_MAP = new HashMap<>();
    // rtp socket map key is rtp port value is rtp socket
    private final static Map<Integer, IRtspSocket> RTSP_SOCKET_MAP = new HashMap<>();


    /**
     * 启动rtsp socket
     *
     * @param port
     */
    public static void startRtspOverUdpSocket(int port,RtspPlayer rtspPlayer,MediaType type) {
        RtpOverUdp rtpOverUdp = new RtpOverUdp(port,rtspPlayer, type);
        RTSP_SOCKET_MAP.put(port, rtpOverUdp);
        JRtspThreadPool.execute(rtpOverUdp);
        RtcpOverUdp rtcpOverUdp = new RtcpOverUdp(port + 1,rtspPlayer,type);
        RTSP_SOCKET_MAP.put(port + 1, rtcpOverUdp);
        JRtspThreadPool.execute(rtcpOverUdp);
    }

    /**
     * 获取rtp rtcp端口
     *
     * @param config
     * @param rtspTrack
     * @return
     */

    public static int getRtspOverUdpPort(RtspConfig config, String rtspTrack, RtspPlayer rtspPlayer , MediaType type) {
        int rtpPortStart = config.getRtpPortStart();
        int rtpPortEnd = config.getRtpPortEnd();
        for (int i = rtpPortStart; i <= rtpPortEnd; i++) {
            // rtp 端口偶数  rtcp端口为后面一位基数
            if (i % 2 == 0) {
                synchronized (RTP_PORT_MAP) {
                    if (!RTP_PORT_MAP.containsKey(i)) {
                        RTP_PORT_MAP.put(i, rtspTrack);
                        startRtspOverUdpSocket(i,rtspPlayer,type);
                        return i;
                    }
                }
            }
        }
        return -1;
    }

    /**
     * 移除rtp端口
     *
     * @param port
     */
    public static void removeRtspPort(int port) {
        RTP_PORT_MAP.remove(port);
        RTSP_SOCKET_MAP.remove(port);
    }

    /**
     * 获取rtp socket
     *
     * @param port
     * @return
     */
    public static IRtspSocket getRtspSocket(int port) {
        return RTSP_SOCKET_MAP.get(port);
    }
}
